home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 427_01 / testware / multicfg.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-03-23  |  8.1 KB  |  323 lines

  1. program MULTIjoy_ConFiG_file_maker;
  2.  
  3.  
  4. (* creates multijoy config files by asking the user to push a specified
  5.    joystick into a specified direction and scanning the printer port for
  6.    changes
  7. *)
  8.  
  9.  
  10. uses  dos,
  11.       crt;
  12.  
  13.  
  14. const direction  : array [1 .. 6] of string
  15.                  = ('left', 'right', 'up', 'down', 'fire', 'extra');
  16.  
  17.       action     : array [1 .. 6] of char
  18.                  = ('l', 'r', 'u', 'd', 'f', '*');
  19.  
  20.  
  21. type  Tpin       = (none, pe, busy);
  22.  
  23.       Taddress   = record
  24.                      address : byte;
  25.                      pin     : Tpin;
  26.                    end;
  27.  
  28.  
  29. var   assignment : array [1 .. 6, 1 .. 6] of Taddress;
  30.       pout,
  31.       p_in       : word;
  32.       multipath  : string;
  33.  
  34.  
  35. procedure error_msg (msg_nr, code : integer);
  36. (* displays error message and halts the program if necessary *)
  37. begin
  38.   writeln ('MULTICFG error message:');
  39.   case msg_nr of
  40.      1 : begin
  41.            writeln ('DOS environment does not contain MULTIPATH (path of config file)');
  42.            halt;
  43.          end;
  44.      2 : begin
  45.            writeln ('Invalid DOS environment variable MULTIPORT (''', chr (code), ''')');
  46.            halt;
  47.          end;
  48.      3 : begin
  49.            writeln ('DOS environment variable MULTIPORT must have only one digit!');
  50.            halt;
  51.          end;
  52.      4 : begin
  53.            writeln ('Config file write error #', code);
  54.            halt;
  55.          end;
  56.      0 : writeln ('Test #', code)
  57.     else begin
  58.       writeln ('critical error - no appropriate error message found (error #', code, ')');
  59.       halt;
  60.     end;
  61.   end;
  62. end;
  63.  
  64.  
  65. procedure init;
  66. (* initializes screen
  67.    reads path to write config file to from DOS environment
  68.    reads printer port number from DOS environment (if set)
  69.    zeros assignment table                                  *)
  70.  
  71.  
  72.   function get_port_nr (multiport : string) : byte;
  73.   (* find printer port number in a string *)
  74.   var port : char;
  75.   begin
  76.     port := multiport [1];
  77.     if not (port in ['1' .. '3']) then error_msg (2, ord (port));
  78.     get_port_nr := ord (port) - ord ('0');
  79.   end;
  80.  
  81.  
  82. (* init *)
  83. var i,
  84.     j            : integer;
  85.     printer_port : byte;
  86.     multiport    : string;
  87. begin
  88.   clrscr;
  89.  
  90.   multipath := getenv ('multipath'); (* read environment variables *)
  91.   multiport := getenv ('multiport');
  92.  
  93.   if multipath           = '' then error_msg (1, 0); (* undefined? *)
  94.   if length (multiport)  >  1 then error_msg (3, 0); (* too long?  *)
  95.   if multiport           = '' then printer_port := 1 (* default!   *)
  96.                               else printer_port := get_port_nr (multiport);
  97.  
  98.   pout := memw [$40:$8 + (printer_port - 1) * 2];
  99.   p_in := pout + 1;
  100.  
  101.   for i := 1 to 6 do
  102.     for j := 1 to 6 do
  103.       with assignment [i, j] do begin
  104.         address := 0;
  105.         pin     := none;
  106.       end;
  107. end;
  108.  
  109.  
  110. procedure test_sticks;
  111. (* ask user to push a specified joystick into a specified direction *)
  112. (* scanning the printer port for changes                            *)
  113.  
  114.  
  115.   function direction_found (var stick : Taddress) : boolean;
  116.   (* finds printer port address that has changed due to user's stick
  117.      movement
  118.      returns TRUE if successful,
  119.              FALSE if aborted by user or intended pin already used   *)
  120.  
  121.  
  122.     function in_port : byte;
  123.     (* reads printer port, i.e. PAPER EMPTY and BUSY bits *)
  124.     begin
  125.       in_port := port [p_in];
  126.     end;
  127.  
  128.  
  129.     procedure out_port (b : byte);
  130.     (* joystick switch address byte output to printer port    *)
  131.     (* always two switches addressed at once                  *)
  132.     (* one is connected to PAPER EMPTY, the other one to BUSY *)
  133.     begin
  134.       port [pout] := b or $10; { $10 provides power supply for multi018}
  135.     end;
  136.  
  137.  
  138.     function pin_unused (add_now : byte; pin_now : Tpin) : boolean;
  139.     (* TRUE if ADDRESS/PIN combination is not used anywhere in ASSIGNMENT *)
  140.     var unused : boolean;
  141.         i,
  142.         j      : integer;
  143.     begin
  144.       unused := true;
  145.       for i := 1 to 6 do
  146.         for j := 1 to 6 do
  147.           with assignment [i, j] do
  148.             if (pin = pin_now) and (address = add_now)
  149.               then unused := false;
  150.  
  151.       pin_unused := unused;
  152.     end;
  153.  
  154.  
  155.     procedure beep (frequency : integer);
  156.     (* beeps *)
  157.     begin
  158.       sound (frequency);
  159.       delay (50);
  160.       nosound;
  161.     end;
  162.  
  163.  
  164.   (* direction_found *)
  165.   var i      : byte;
  166.       pin    : Tpin;
  167.       signal : byte;
  168.   begin
  169.     i := 0;
  170.     repeat until readkey <> '';
  171.  
  172.     repeat
  173.       out_port (i);
  174.       signal := in_port;
  175.       pin := none;
  176.       if (signal and $20) <> 0 then pin := pe;
  177.       if (signal and $80) =  0 then pin := busy;
  178.       inc (i);
  179.     until (pin <> none) or (i > 15);
  180.  
  181.     if pin <> none
  182.       then begin
  183.         if pin_unused (i - 1, pin)
  184.           then begin
  185.             stick.address   := i - 1;
  186.             stick.pin       := pin;
  187.             direction_found := true;
  188.             beep (440);
  189.           end else begin
  190.             direction_found := false;             (* pin already used *)
  191.             beep (880);
  192.           end;
  193.       end else begin
  194.         direction_found := false;
  195.         beep (880);
  196.         beep (440);
  197.         beep (880);
  198.       end;
  199.   end;
  200.  
  201.  
  202. (* test_sticks *)
  203. var j,
  204.     k,
  205.     xtracount : integer;
  206. begin
  207.   xtracount := 0;
  208.   for j := 1 to 6 do begin
  209.     clrscr;
  210.     writeln ('Press any key when you have moved the joystick as requested!');
  211.     writeln;
  212.     writeln ('Joystick #', j);
  213.     for k := 1 to 5 do begin
  214.       writeln ('     ', direction [k]);
  215.       repeat until direction_found (assignment [j, k]);
  216.     end;
  217.     if xtracount < 2 then begin
  218.       writeln ('     ', direction [6]);
  219.       if direction_found (assignment [j, 6]) then inc (xtracount);
  220.     end;
  221.   end;
  222. end;
  223.  
  224.  
  225. procedure write_file;
  226. (* write the config information to a disk file *)
  227. var config   : text;
  228.  
  229.  
  230.     procedure upcase_str (var to_upcase : string);
  231.     (* upcases a string *)
  232.     var i : integer;
  233.     begin
  234.       for i := 1 to length (to_upcase) do
  235.         to_upcase [i] := upcase (to_upcase [i]);
  236.     end;
  237.  
  238.  
  239.     function action_written (add_now : byte; pin_now : Tpin) : boolean;
  240.     (* writes a specified action to config file
  241.        returns TRUE  if action written
  242.        returns FALSE if no action found *)
  243.     var found : boolean;
  244.         j,
  245.         k     : byte;
  246.     begin
  247.       found := false;
  248.       j := 0;
  249.       repeat
  250.         inc (j);
  251.         k := 0;
  252.         repeat
  253.           inc (k);
  254.           with assignment [j, k] do
  255.             if (address = add_now) and (pin = pin_now)
  256.               then begin
  257.                 found := true;
  258.                 write (config, ' ', j, ' ', action [k]);
  259.               end;
  260.         until (k >= 6) or found;
  261.       until (j >= 6) or found;
  262.       action_written := found;
  263.     end;
  264.  
  265.  
  266. var multicfg : string [8];
  267.     answer   : char;
  268.     error    : integer;
  269.     i,
  270.     j,
  271.     k        : byte;
  272. (* write_file *)
  273. begin
  274.   repeat
  275.     clrscr;
  276.     writeln ('Name of config file: ');
  277.     repeat
  278.       readln(multicfg);
  279.     until (length (multicfg) > 0) and (pos ('.', multicfg) = 0);
  280.     upcase_str (multicfg);
  281.  
  282.     if multipath[length(multipath)] = '\' then
  283.       assign (config, multipath + multicfg + '.cfg')
  284.     else
  285.       assign (config, multipath + '\' + multicfg + '.cfg');
  286.  
  287.     {$I-}
  288.     reset (config);
  289.     {$I+}
  290.     error := ioresult;
  291.     if error = 0 then begin
  292.       writeln;
  293.       writeln (multicfg, '.CFG already exists. Overwrite?');
  294.       repeat
  295.         answer := upcase (readkey);
  296.       until answer in ['Y', 'N'];
  297.     end;
  298.   until (error <> 0) or (answer = 'Y');
  299.   {$I-}
  300.   rewrite (config);
  301.   {$I+}
  302.   error := ioresult;
  303.   if error <> 0 then error_msg (4, error);
  304.   for i := 0 to 15 do begin
  305.     write (config, i);
  306.     if i < 10 then write (config, ' ');
  307.     if not action_written (i, pe)   then write (config, ' 1 *');
  308.     if not action_written (i, busy) then write (config, ' 2 *');
  309.     if i < 15 then writeln (config);
  310.   end;
  311.  
  312.   close (config);
  313.  
  314.   writeln (multicfg, '.CFG written successfully');
  315. end;
  316.  
  317.  
  318. (* multijoy_config_file_maker *)
  319. begin
  320.   init;
  321.   test_sticks;
  322.   write_file;
  323. end.